#include "stdafx.h"
#include <string>
#include <locale.h>

#include "encode.h"

#ifdef WIN32
char_ptr Unicode::utf8_gbk(  const char* utf8_str )
{
	char_ptr ptr;
	std::string	utf8_buf = utf8_str;
	if( *utf8_str )
	{
		int result = 0;
		int len = result = MultiByteToWideChar(CP_UTF8, 0, utf8_buf.c_str(), -1, NULL,0);
		if( result == 0 )
		{
			char *NullStr	= new char[1];
			NullStr[0]	= 0x00;
			ptr.reset( NullStr );
			return ptr;
		}

		WCHAR* wszGBK = new WCHAR[len+1];
		memset(wszGBK, 0, len * 2 + 2);
		result = MultiByteToWideChar(CP_UTF8, 0, utf8_buf.c_str(), -1, wszGBK, len);
		if( result == 0 )
		{
			delete[] wszGBK; 
			char *NullStr	= new char[1];
			NullStr[0]	= 0x00;
			ptr.reset( NullStr );
			return ptr;
		}
		len = result = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
		if( result == 0 )
		{
			delete[] wszGBK; 
			char *NullStr	= new char[1];
			NullStr[0]	= 0x00;
			ptr.reset( NullStr );
			return ptr;
		}

		char *szGBK=new char[len + 1];
		memset(szGBK, 0, len + 1);
		result = WideCharToMultiByte (CP_ACP, 0, wszGBK, -1, szGBK, len, NULL,NULL);
		if( result == 0 )
		{
			delete[] wszGBK; 
			delete[] szGBK;
			char *NullStr	= new char[1];
			NullStr[0]	= 0x00;
			ptr.reset( NullStr );
			return ptr;
		}

		delete[] wszGBK; 
		ptr.reset( szGBK );
	}
	else
	{
		char *NullStr	= new char[1];
		NullStr[0]	= 0x00;
		ptr.reset( NullStr );
	}
	return ptr;
}

char_ptr Unicode::gbk_utf8(  const char* gbk_str )
{
	char_ptr buf;
	std::string	gbk_buf = gbk_str;
	if( gbk_buf.size() )
	{
		int len=MultiByteToWideChar(CP_ACP, 0, gbk_buf.c_str(), -1, NULL,0);
		WCHAR* wszUtf8 = new WCHAR[len+1];
		memset(wszUtf8, 0, len * 2 + 2);
		MultiByteToWideChar(CP_ACP, 0, gbk_buf.c_str(), -1, wszUtf8, len);
		len = WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, NULL, 0, NULL, NULL);
		char *szUtf8=new char[len + 1];
		memset(szUtf8, 0, len + 1);
		WideCharToMultiByte (CP_UTF8, 0, wszUtf8, -1, szUtf8, len, NULL,NULL);
		delete[] szUtf8;
		buf.reset((char*)wszUtf8);
	}
	return buf;
}

std::string Unicode::WChar2Ansi(LPCWSTR pwszSrc)
{
	int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
	if (nLen<= 0) return std::string("");
	char* pszDst = new char[nLen];
	if (NULL == pszDst) return std::string("");
	WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
	pszDst[nLen -1] = 0;
	std::string strTemp(pszDst);
	delete [] pszDst;
	return strTemp;
}
//Converting a Ansi string to WChar string
std::wstring Unicode::Ansi2WChar(LPCSTR pszSrc, int nLen)
{
	if( 0 == nLen )
		return std::wstring();
	int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
	if(nSize <= 0) return NULL;
	WCHAR *pwszDst = new WCHAR[nSize+1];
	if( NULL == pwszDst) return NULL;
	MultiByteToWideChar(CP_ACP, 0,(LPCSTR)pszSrc, nLen, pwszDst, nSize);
	pwszDst[nSize] = 0;
	if( pwszDst[0] == 0xFEFF) // skip Oxfeff
		for(int i = 0; i < nSize; i ++)
			pwszDst[i] = pwszDst[i+1];
	std::wstring wcharString(pwszDst);
	delete pwszDst;
	return wcharString;
}
#else
// 使用 iconv 实现
char_ptr Unicode::utf8_gbk(  const char* utf8_str )
{
	return char_ptr();
}

char_ptr Unicode::gbk_utf8(  const char* utf8_str )
{
	return char_ptr();
}

#endif


// std::string Unicode::ws2s(const std::wstring& ws)
// {
// 	std::string curLocale = setlocale(LC_ALL, NULL);        // curLocale = "C";
// 	setlocale(LC_ALL, "chs");
// 	const wchar_t* _Source = ws.c_str();
// 	size_t _Dsize = 2 * ws.size() + 1;
// 	char *_Dest = new char[_Dsize];
// 	memset(_Dest,0,_Dsize);
// 	wcstombs(_Dest,_Source,_Dsize);
// 	std::string result = _Dest;
// 	delete []_Dest;
// 	setlocale(LC_ALL, curLocale.c_str());
// 	return result;
// }
// 
// std::wstring Unicode::s2ws(const std::string& s)
// {
// 	setlocale(LC_ALL, "chs"); 
// 	const char* _Source = s.c_str();
// 	size_t _Dsize = s.size() + 1;
// 	wchar_t *_Dest = new wchar_t[_Dsize];
// 	wmemset(_Dest, 0, _Dsize);
// 	mbstowcs(_Dest,_Source,_Dsize);
// 	std::wstring result = _Dest;
// 	delete []_Dest;
// 	setlocale(LC_ALL, "C");
// 	return result;
// }
